﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EWSEditor.CRM.Forms
{
    public partial class DiagnosticForm : Form
    {
        

        public DiagnosticForm()
        {
            InitializeComponent();
            treeDiagnostics.ImageList = new ImageList();
            treeDiagnostics.ImageList.Images.Add(Properties.Resources.information);
            treeDiagnostics.ImageList.Images.Add(Properties.Resources.GreenCheck);
            treeDiagnostics.ImageList.Images.Add(Properties.Resources.warning);
            treeDiagnostics.ImageList.Images.Add(Properties.Resources.error);
            //lblConfigurationChecks.Text = "Configuration Diagnostics check for system and user configurations\n that can cause certain problems.";
            //lblIncomingEmail.Text = "Incoming Email Diagnostics check for issues in user and mailbox configurations\n that can cause emails to fail to process or process slower than expected.";
            //lblACTSync.Text = "ACT Diagnostics check for issues in user and mailbox configurations\n that can cause ACT synchronization to fail or process slowly.";

        }

        /// <summary>
        /// Used to display debug information from a background worker that failed.
        /// </summary>
        /// <param name="Message">Message to be shown.</param>
        /// <param name="Caption">Caption for the message.</param>
        /// <param name="form">The DiagnosticForm instance to display the message.</param>
        public static void ShowMessage(string Message, string Caption, DiagnosticForm form)
        {
            if (form.InvokeRequired)
            {
                form.Invoke(new Action<string, string>(DisplayMessage));
            }
            else
            {
                MessageBox.Show(Message, Caption);
            }
        }

        private static void DisplayMessage(string arg1, string arg2)
        {
            MessageBox.Show(arg1, arg2);
        }

        private void DiagnosticForm_Load(object sender, EventArgs e)
        {
            ShowBlankPanel();
            InitializeDiagnosticAsync();
        }

        private void InitializeDiagnosticAsync()
        {
            Diagnostic diag = new Diagnostic();

            BackgroundWorker bgWorker = new BackgroundWorker();
            bgWorker.DoWork += (sender, e) =>
            {
                diag.Initialize(this);
            };

            bgWorker.RunWorkerCompleted += (sender, e) =>
            {
                BuildForm(diag);
            };

            bgWorker.RunWorkerAsync();

            
        }

        private void BuildForm(Diagnostic diag)
        {
            foreach (DiagnosticCheck diagCheck in diag.ConfigurationChecks)
            {
                TreeNode node = BuildTreeNode(diagCheck);
                Invoke(new Action<TreeNode>(AddNode), node);

                if ((diagCheck.DiagnosticResult != DiagnosticCheckResult.Information) && (diagCheck.DiagnosticResult != DiagnosticCheckResult.Success))
                {
                    if (node.Parent.ImageIndex == 3)
                    {
                        continue; 
                    }
                    node.Parent.ImageIndex = node.ImageIndex;
                }
            }

            Invoke(new Action<Panel>(HidePanel), panelLoading);


        }

        private void HidePanel(Panel panel)
        {
            panel.Visible = false;
        }

        private void AddNode(TreeNode node)
        {
            //OrgDBOrgSettings are the first checks added to the ConfigurationChecks collection
            //We add them as the first node w/ a parent node type here.

            if (((DiagnosticCheck)node.Tag).DiagnosticCheckType == DiagnosticType.OrgDbOrgSetting)
            {
                if (treeDiagnostics.Nodes[0].Nodes.Count == 0)
                {
                    TreeNode orgDBorgHeaderNode = new TreeNode { Text = "OrgDBOrgSettings" };
                    treeDiagnostics.Nodes[0].Nodes.Add(orgDBorgHeaderNode);
                }

                treeDiagnostics.Nodes[0].Nodes[0].Nodes.Add(node);
                return;
            }

            if (((DiagnosticCheck)node.Tag).DiagnosticCheckType == DiagnosticType.Configuration)
            {
                treeDiagnostics.Nodes[0].Nodes.Add(node);
                return;
            }

            if (((DiagnosticCheck)node.Tag).DiagnosticCheckType == DiagnosticType.IncomingEmail)
            {
                treeDiagnostics.Nodes[1].Nodes.Add(node);
                return;
            }

            if (((DiagnosticCheck)node.Tag).DiagnosticCheckType == DiagnosticType.ACT)
            {
                treeDiagnostics.Nodes[2].Nodes.Add(node);
                return;
            }
        }

        private TreeNode BuildTreeNode(DiagnosticCheck diagCheck)
        {
            TreeNode node = new TreeNode();
            node.Tag = diagCheck;
            node.Text = diagCheck.CheckName;

            if (diagCheck.DiagnosticResult == DiagnosticCheckResult.Information)
            {
                node.ImageIndex = 0;
                node.SelectedImageIndex = 0;
            }

            if (diagCheck.DiagnosticResult == DiagnosticCheckResult.Success)
            {
                node.ImageIndex = 1;
                node.SelectedImageIndex = 1;
            }

            if (diagCheck.DiagnosticResult == DiagnosticCheckResult.Warning)
            {
                node.ImageIndex = 2;
                node.SelectedImageIndex = 2;
            }

            if (diagCheck.DiagnosticResult == DiagnosticCheckResult.Error)
            {
                node.ImageIndex = 3;
                node.SelectedImageIndex = 3;   
            }

            return node;

        }

        private void treeDiagnostics_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (null != e.Node.Parent)
            {
                if (e.Node.Parent.Text == "OrgDBOrgSettings")
                {
                    //Show OrgDBOrgPanel
                    ShowOrgDBOrgPanel(e);
                    SetAlertPanel(e.Node);
                    return;
                }
            }

            if (e.Node == treeDiagnostics.Nodes[0])
            {
                e.Node.SelectedImageIndex = e.Node.ImageIndex;
                ShowBlankPanel();
                return;
            }

            if (e.Node == treeDiagnostics.Nodes[1])
            {
                e.Node.SelectedImageIndex = e.Node.ImageIndex;
                ShowBlankPanel();
                return;
            }

            if (e.Node == treeDiagnostics.Nodes[2])
            {
                e.Node.SelectedImageIndex = e.Node.ImageIndex;
                ShowBlankPanel();
                return;
            }

            if (e.Node == treeDiagnostics.Nodes[0].Nodes[0])
            {
                e.Node.SelectedImageIndex = e.Node.ImageIndex;
                ShowBlankPanel();
                return;
            }

            ShowBasePanel(); //Removes blank / OrgDBOrgSettingPanels if they are visible
            txtSymptom.Text = ((DiagnosticCheck)e.Node.Tag).Symptom;
            txtCause.Text = ((DiagnosticCheck)e.Node.Tag).Cause;
            txtResolution.Text = ((DiagnosticCheck)e.Node.Tag).Resolution;
            txtTechnicalDetails.Text = ((DiagnosticCheck)e.Node.Tag).TechnicalDetails;

            if (null != ((DiagnosticCheck)e.Node.Tag).DynamicHelpUrl)
            {
                linkDynamicHelp.Text = ((DiagnosticCheck)e.Node.Tag).DynamicHelpUrl;
                lblDynamicHelp.Visible = true;
                linkDynamicHelp.Visible = true;
            }
            else
            {
                lblDynamicHelp.Visible = false;
                linkDynamicHelp.Visible = false;
            }

            if (((DiagnosticCheck)e.Node.Tag).ShowFixIt)
            {
                btnFixIt.Visible = true;
            }
            else
            {
                btnFixIt.Visible = false;
            }

            SetAlertPanel(e.Node);


        }

        private void ShowOrgDBOrgPanel(TreeNodeMouseClickEventArgs e)
        {
            lblCurrentValueValue.Text = ((DiagnosticCheck)e.Node.Tag).OrgSettingCurrentVal;
            lblOrgDbOrgSetting.Text = ((DiagnosticCheck)e.Node.Tag).CheckName;
            txtOrgDbOrgSettingPurpose.Text = ((DiagnosticCheck)e.Node.Tag).OrgSettingUseCase;
            linkOrgDbOrgSetting.Text = ((DiagnosticCheck)e.Node.Tag).DynamicHelpUrl;
            pnlBlank.Hide();
            pnlBase.Hide();
            pnlOrgDbOrgSetting.Show();
            panelAlert.Show();
            
            
        }

        private void SetAlertPanel(TreeNode Node)
        {
            picAlert.Visible = true;

            if (((DiagnosticCheck)Node.Tag).DiagnosticResult == DiagnosticCheckResult.Information)
            {
                lblAlert.Text = "Information";
                panelAlert.BackColor = Color.LightBlue;
                picAlert.Image = Properties.Resources.information;
            }

            if (((DiagnosticCheck)Node.Tag).DiagnosticResult == DiagnosticCheckResult.Warning)
            {
                lblAlert.Text = "Warning";
                panelAlert.BackColor = Color.Orange;
                picAlert.Image = Properties.Resources.warning;
            }

            if (((DiagnosticCheck)Node.Tag).DiagnosticResult == DiagnosticCheckResult.Error)
            {
                lblAlert.Text = "Test Failed";
                panelAlert.BackColor = Color.Crimson;
                picAlert.Image = Properties.Resources.error;
            }

            if (((DiagnosticCheck)Node.Tag).DiagnosticResult == DiagnosticCheckResult.Success)
            {
                lblAlert.Text = "Test Passed";
                panelAlert.BackColor = Color.LimeGreen;
                picAlert.Image = Properties.Resources.GreenCheck;
            }
        }

        private void ShowBasePanel()
        {
            pnlBlank.Hide();
            pnlOrgDbOrgSetting.Hide();
            panelAlert.Show();
            pnlBase.Show();
        }

        private void ShowBlankPanel()
        {
           
            pnlBase.Hide();
            pnlOrgDbOrgSetting.Hide();
            pnlBlank.Show();
            panelAlert.BackColor = Color.LightBlue;
            panelAlert.Show();
            picAlert.Visible = false;
            lblAlert.Text = "Select a Test Result";
            txtSymptom.Text = "";
            txtCause.Text = "";
            txtResolution.Text = "";
            txtTechnicalDetails.Text = "";
            btnFixIt.Visible = false;
        }

        private void panelSelectNode_Paint(object sender, PaintEventArgs e)
        {

        }

        private void btnFixIt_Click(object sender, EventArgs e)
        {
            DiagnosticCheck diagCheck = (DiagnosticCheck)treeDiagnostics.SelectedNode.Tag;
            diagCheck.CallMethod(diagCheck.DelegatedFixItMethod);
        }

        private void linkDynamicHelp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start(linkDynamicHelp.Text);
        }

        private void lblTechnicalDetailsExpanded_Click(object sender, EventArgs e)
        {
            CollapseTechnicalDetails();
        }

        private void picDetailsExpanded_Click(object sender, EventArgs e)
        {
            CollapseTechnicalDetails();
        }

        private void CollapseTechnicalDetails()
        {
            picDetailsExpanded.Visible = false;
            lblTechnicalDetailsExpanded.Visible = false;
            txtTechnicalDetails.Visible = false;

            lblTechnicalDetailsCollapsed.Visible = true;
            picDetailsCollapsed.Visible = true;
        }

        private void lblTechnicalDetailsCollapsed_Click(object sender, EventArgs e)
        {
            ExpandTechnicalDetails();
        }

        private void picDetailsCollapsed_Click(object sender, EventArgs e)
        {
            ExpandTechnicalDetails();
        }

        private void ExpandTechnicalDetails()
        {
            lblTechnicalDetailsExpanded.Visible = true;
            picDetailsExpanded.Visible = true;
            txtTechnicalDetails.Visible = true;

            lblTechnicalDetailsCollapsed.Visible = false;
            picDetailsCollapsed.Visible = false;
        }

        private void linkOrgDbOrgSetting_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start(linkOrgDbOrgSetting.Text);
        }
    }

}
